package com.rslai.commons.validator.jsonvalidator;

import com.rslai.commons.validator.jsonvalidator.exception.JsonSyntaxError;
import com.rslai.commons.validator.jsonvalidator.matchers.JsonAssert;
import com.rslai.commons.validator.jsonvalidator.schema.javacc.TokenMgrError;
import com.rslai.commons.validator.jsonvalidator.util.ReflectionUtils;
import com.rslai.commons.validator.jsonvalidator.validate.JavaCCSchemaProvider;
import org.apache.commons.lang.StringUtils;

import static com.rslai.commons.validator.jsonvalidator.util.StringUtil.deleteBlank;

/**
 * JSON校验工具，根据规则校验JSON是否合法
 */
public class JsonValidator {
    public static Boolean arrayDefaultOrderValidate = Boolean.FALSE;
    private static final JSONSchemaProvider jsonSchemaProvider = new JavaCCSchemaProvider();

    /**
     * 根据规则校验JSON字符串是否合法
     * @param schema 规则
     * @param json json字符串
     */
    public static void validate(String schema, String json) {
        if (StringUtils.equals(schema, json)) {
            return;
        }
        if (StringUtils.isBlank(schema)) {
            if (StringUtils.isNotBlank(json)) {
                JsonAssert.fail("JSON数据校验失败", schema, json);
            }
            return;
        }
        try {
            createSchema(schema).validate(deleteBlank(json));
        } catch (AssertionError ae) {
            StringBuilder sb = new StringBuilder(ae.getMessage());
            sb.append("\n     response: ").append(json).append("\n");
            ReflectionUtils.setFieldValue(ae, "detailMessage", sb.toString());
            throw ae;
        }
    }

    /**
     * 创建JsonSchema，根据传入的schema字符串生成JsonSchema
     * @param schema schema字符串
     * @return JsonSchema
     */
    public static JsonSchema createSchema(String schema) {
        try {
            return jsonSchemaProvider.getSchema(deleteBlank(schema));
        } catch (TokenMgrError tokenMgrError) {
            String message = "schema 语法错误";
            message += "\n Schema: " + schema;
            message += "\n Message: " + tokenMgrError.getMessage();
            throw new JsonSyntaxError(message, tokenMgrError);
        }
    }

}